/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief ecan1000hr driver for Linux from ASRobo
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 */
#ifndef _ECAN1000HR_HPP_
#define _ECAN1000HR_HPP_
//#include "TGIMI_PROTOCOL_AVANT_CMD_V3.h"

//#include "TGIMI_PROTOCOL_AVANT_REPLY_V3.h"
#include "ASRoboBus.hpp"
#include "owndebug.h"
#ifdef LINUX_OS
#include <ecanlib.h>
#include <ecanioctl.h>
#include <ecan_types.h>
#else
#define u32_t unsigned int
#endif


#define ECAN1000DRV_BOARD_TYPE 1000



class CEcan1000hr : public CASRoboBus
{
  
public :
#ifdef LINUX_OS
  /**
   * This typedef is simply because it looks better :)
   */
  typedef ECAN_MESSAGE_STRUCTURE	TEcanMessage;
  
  typedef enum BitRates EBitRates;
#endif
  
    /*Default constructor*/
  CEcan1000hr();
  
  
  /*
   * Advanced Constructor.
   * NOTE: USE THIS CLASS ONLY IN ONE THREAD.
   *
   * @param rxQueue	       The size of the receive queue
   * @param txQueue	       The size of the transmit queue
   * @param aBitRate           The used bitrate. Choose the value
   *                           corresponding the wanted bitrate
   *                           0 = R50000,
   *                           1 = R62500,
   *                           2 = R100000,
   *                           3 = R125000,
   *                           4 = R250000,
   *                           5 = R500000,
   *                           6 = R1000000
   */
  CEcan1000hr(int aRxQueue, int aTxQueue,int aBitRate);
  
  
  /**
   * Destructor.
   */
  virtual ~CEcan1000hr();
  
  /**
   * Opens the can driver.
   * 
   *
   * @return                KBusStatusOK on ok, KBusStatusError on error.
   */
  EBusStatus Open(void);
  
  EBusStatus Init(void);
  /**
   * Reads data from can bus. The read only reads as much data as is available.
   *
   * @param buffer          Buffer to read data to, must be atleast 'buffer_size' bytes.
   * @param buffer_size     Storage available
   * @return                Negative on error, otherwise the number of bytes
   *                        stored on the 'buffer'
   */
  int Read(unsigned char *buffer, int buffer_size);
  
  /**
   * Writes data to Can. 
   *
   * @param buffer          Buffer to write to can, must be atleast 'buffer_size' bytes.
   * @param buffer_size     Size of the buffer to write
   * @return                The number of writed bytes or -1 in case of an error
   */
  int Write(const unsigned char *buffer, int buffer_size);

  
  /**
   * Reads until the full timeout has elapsed OR packet is COMPLETE.
   *
   * @param buffer          Buffer to read data to, must be atleast 'buffer_size' bytes.
   * @param block_size      Number of bytes to read
   * @param timeout_ms      Timeout time in ms. -1 = no timeout
   * @return                0 if timeout has elapsed, else buffer_size
   */
  int ReadBlock(unsigned char *buffer, int block_size, int timeout_ms = -1);
  
  /**
   * Writes until the full timeout has elapsed OR packet is COMPLETE.
   *
   * @param buffer         Data to write to can.
   * @param block_size     Size of the block
   * @param timeout_ms     Timeout time in ms. -1 = no timeout
   * @return               the number of bytes writed to can
   */
  int WriteBlock(unsigned char *buffer, int block_size, int timeout_ms = -1);

  /**
   * Sets the sending data structure parameters
   *
   *
   * @param aExtended      Extended Frame Format
   * @param aRemote        Remote Frame request
   * @param aID            Message id
   * @param aNextMsg       Next message available in a queue
   * @param aDontQueueUse  
   * return                True, if structure params is set.
   */
  bool SetStructureParameters(bool aExtended,
			      bool aRemote,
			      u32_t aID,
			      bool aNextMsg,
			      bool aDontQueueUse);

  /*
   * Closes the can
   *
   * @return                KBusStatusOK on ok, KBusStatusError on error.
   */
  
  EBusStatus Close(void);

  /**
   * Wait to Write, not Implemented. It's here because ASRobo_bus want it.
   * The function returns only KBusStatusUnimplemented
   *
   * @param x           nothing :)
   * @return            KBusStatusUnimplemented
   */
  EBusStatus WaitToWrite(int x) { return KBusStatusUnimplemented; }

  /**
   * Wait to Read, not Implemented. It's here because ASRobo_bus want it.
   * The function returns only KBusStatusUnimplemented
   *
   * @param x           nothing :)
   * @return            KBusStatusUnimplemented
   */
  EBusStatus WaitToRead(int x) { return KBusStatusUnimplemented; }
  /**
   *
   * Set up a filter for standard frames in single filter mode
   *
   * @param aID_ACR          11-bit Acceptance Code for message ID.
   * @param aID_AMR          11-bit Acceptance Mask for message ID.
   * @param aRTR_ACR         1-bit Acceptance Code for Remote Transmission
   *                         Request
   * @param aRTR_AMR         1-bit Acceptance Mask for Remote Transmission
   *                         Request
   * @param aData_ACR        16-bit Acceptance Code for first 16 bits of
   *                         message
   * @param aData_AMR        16-bit Acceptance Mask for first 16 bits of
   *                         message
   *
   * @return                 true on succeed.
   */
  bool SetSingleFilter(unsigned int aID_ACR,unsigned int aID_AMR,
		       unsigned int aRTR_ACR,unsigned int aRTR_AMR,
		       unsigned int aData_ACR, unsigned int aData_AMR);
  
  
  
  
private :
  

 

  int iRxQueue;     ///< The size of the receive queue
  int iTxQueue;     ///< The size of the transmit queue
  int iBitRate;     ///< The speed of the bus. The BitRates definition is in ecan1000drv_rates[]
  int iDeviceHandle;
  bool iExtended;
  bool iRemote;
  u32_t iID;
  bool iNextMsg;
  bool iDontQueueUse;
  
  //Filter params
  unsigned int iID_ACR,iID_AMR,iRTR_ACR,iRTR_AMR;
  unsigned int iData_ACR, iData_AMR;
  
    CEcan1000hr(const CEcan1000hr &) :
      iRxQueue(0),
      iTxQueue(0),
      iBitRate(0),
      iDeviceHandle(0),
      iExtended(false),
      iRemote(false),
      iID(0),
      iNextMsg(false),
      iDontQueueUse(false),
      iID_ACR(0),
      iID_AMR(0),
      iRTR_ACR(0),
      iRTR_AMR(0),
      iData_ACR(0),
      iData_AMR(0)
    {}

    CEcan1000hr& operator=(const CEcan1000hr &) { return *this; }
  };


#ifdef LINUX_OS
  extern BitRates ecan1000drv_rates[];
#endif
    
#endif //_ECAN1000HR_HPP_

